package com.dwy.decodemjpeg

import java.util.Locale
import java.util.regex.Pattern

object ObjectUtil {
    /**
     * 将int转为高字节在前，低字节在后的byte数组
     *
     * @param n int
     * @return byte[]
     */
    fun toHH(n: Int): ByteArray {
        val b = ByteArray(4)
        b[3] = (n and 0xff).toByte()
        b[2] = (n shr 8 and 0xff).toByte()
        b[1] = (n shr 16 and 0xff).toByte()
        b[0] = (n shr 24 and 0xff).toByte()
        return b
    }

    /**
     * @author xavi
     * 动态接收参数
     * 将给的数组合并成一个数组
     */
    fun arrayCopy(vararg arrays: ByteArray): ByteArray {
        //数组长度
        var arrayLength = 0
        //目标数组的起始位置
        var startIndex = 0
        for (file in arrays) {
            arrayLength = arrayLength + file.size
        }
        val fileArray = ByteArray(arrayLength)
        for (i in arrays.indices) {
            if (i > 0) {
                //i为0 时，目标数组的起始位置为0 ,i为1时，目标数组的起始位置为第一个数组长度
                //i为2时，目标数组的起始位置为第一个数组长度+第二个数组长度
                startIndex = startIndex + arrays[i - 1].size
            }
            System.arraycopy(arrays[i], 0, fileArray, startIndex, arrays[i].size)
        }
        return fileArray
    }

    /**
     * byte数组转int
     *
     * @param bytes
     * @return
     */
    fun bytes2Int(bytes: ByteArray): Int {
        var result = 0
        //将每个byte依次搬运到int相应的位置
        result = bytes[0].toInt() and 0xff
        result = result shl 8 or (bytes[1].toInt() and 0xff)
        result = result shl 8 or (bytes[2].toInt() and 0xff)
        result = result shl 8 or (bytes[3].toInt() and 0xff)
        return result
    }

    /**
     * 重组byte[]数组
     *
     * @param a
     * @param b
     * @param begin
     * @param end
     * @return
     */
    fun mergebyte(a: ByteArray, b: ByteArray, begin: Int, end: Int): ByteArray {
        val add = ByteArray(a.size + end - begin)
        var i = 0
        i = 0
        while (i < a.size) {
            add[i] = a[i]
            i++
        }
        var k = begin
        while (k < end) {
            add[i] = b[k]
            k++
            i++
        }
        return add
    }

    /**
     * 检查IP地址是否合法
     *
     * @param str
     * @return
     */
    fun ipCheck(str: String?): Boolean {
        if (str != null && !str.isEmpty()) {
            val pattern =
                "^(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])(\\.(\\d|[1-9]\\d|1\\d{2}|2[0-4]\\d|25[0-5])){3}$"
            return if (str.matches(pattern.toRegex())) true else false
        }
        return false
    }

    fun bytes2Hex(bytes: ByteArray): String {
        return parseBytesToHexString(bytes, false, "") ?: ""
    }

    fun parseBytesToHexString(src: ByteArray?, upperCase: Boolean, gap: String?): String? {
        val stringBuilder = StringBuilder("")
        if (src == null || src.size == 0) {
            return null
        }
        for (i in src.indices) {
            val v = (src[i].toInt() and 0xFF).toByte()
            var hv = Integer.toHexString(v.toInt())
            if (hv.length < 2) {
                stringBuilder.append(0)
            } else if (hv.length > 2) {
                hv = hv.substring(hv.length - 2)
            }
            if (i == src.size - 1) {
                stringBuilder.append(if (upperCase) hv.uppercase(Locale.getDefault()) else hv)
            } else {
                stringBuilder.append(if (upperCase) hv.uppercase(Locale.getDefault()) else hv)
                    .append(gap)
            }
        }
        return stringBuilder.toString()
    }

    fun parseHexStringToBytes(hexString: String?): ByteArray {
        var src = hexString
        if (src == null || src.isEmpty()) {
            return ByteArray(0)
        }
        src = src.replace(" ", "").replace("-", "").replace("_", "")
        val byteArray = ByteArray(if (src.length % 2 == 0) src.length / 2 else src.length / 2 + 1)
        var i = 0
        while (i < src.length) {
            val segString =
                if (i == src.length - 1) "0" + src.substring(i, i + 1) else src.substring(i, i + 2)
            if (!Pattern.compile("^[0-9a-fA-F]{2}$").matcher(segString).matches()) {
                return ByteArray(0)
            }
            byteArray[i / 2] = segString.toInt(16).toByte()
            i += 2
        }
        return byteArray
    }

    fun getCRCByteData(bt: ByteArray): ByteArray {
        var sum = 0
        for (i in 1 until bt.size - 2) {
            if (bt[i] < 0) {
                val temp = bt[i].toInt()
                sum += temp
                continue
            }
            sum += bt[i].toInt()
        }
        val crcbyte = ByteArray(2)
        crcbyte[0] = (sum shr 8).toByte()
        crcbyte[1] = sum.toByte()
        return crcbyte
    }

    fun concatByteArrayList(byteArrayList: ArrayList<ByteArray>): ByteArray {
        var size = 0
        for (i in byteArrayList.indices) {
            size += byteArrayList[i].size
        }
        val data = ByteArray(size)
        var destPos = 0
        for (i in byteArrayList.indices) {
            val it = byteArrayList[i]
            if (it.isEmpty()) continue
            System.arraycopy(it, 0, data, destPos, it.size)
            destPos += it.size
        }
        return data
    }

    fun subBytes(bytes: ByteArray?, start: Int, len: Int): ByteArray {
        if (bytes == null || bytes.size < len || len == 0) {
            return ByteArray(0)
        } else if (bytes.size == len) {
            return bytes
        }
        val bs = ByteArray(len)
        for (i in 0 until len) {
            bs[i] = bytes[start + i]
        }
        return bs
    }

    fun compareBytesEquals(buffer1: ByteArray?, buffer2: ByteArray?): Boolean {
        if (buffer1 == null || buffer2 == null || buffer1.size != buffer2.size) {
            return false
        }
        for (i in buffer1.indices) {
            if (buffer1[i] != buffer2[i]) {
                return false
            }
        }
        return true
    }

    fun parseListBytesToByteArray(list: List<Byte>): ByteArray {
        return ByteArray(list.size).apply {
            for (i in list.indices) {
                this[i] = list[i]
            }
        }
    }
}